﻿#region 참조 네임스페이스

using System;
using System.Runtime.InteropServices;

#endregion

namespace Skying.Net.Sockets
{
	/// <summary>
	/// TCP 프로토콜의 Keep Alive 설정 정보에 대한 구조체를 정의한다.
	/// </summary>
	/// <see cref="System.Net.Sockets.Socket.IOControl"/>에 의한 Keep Alive 설정에 사용되며, <see cref="System.Net.Sockets.IOControlCode"/> 옵션을 <see cref="System.Net.Sockets.IOControlCode.KeepAliveValues"/>로 설정해야 한다.
	//[StructLayout(LayoutKind.Explicit)]
	struct TcpKeepAliveOptions
	{
		#region 변수

		/// <summary>
		/// Keep Alive 동작 여부를 나타내며, 1이면 ON, 0이면 OFF로 설정된다.(<see cref="bool"/> 타입과 동일하다.)
		/// </summary>
		public uint _turn;

		/// <summary>
		/// Keep Alive 신호를 주고 받는 주기를 나타낸다.
		/// </summary>
		public uint _keepAliveTime;

		/// <summary>
		/// Keep Alive 신호에 대한 응답이 없을 때, Keep Alive 신호를 반복적으로 주고 받는 주기를 나타낸다.
		/// </summary>
		public uint _keepAliveInterval;

		#endregion

		#region 변환

		/// <summary>
		/// <see cref="TcpKeepAliveOptions"/> 정보를 바이트 배열로 변환한다.
		/// </summary>
		/// <returns><see cref="TcpKeepAliveOptions"/> 정보의 바이트 배열이 반환된다.</returns>
		public byte[] ToArray()
		{
			var data = new[] { this._turn, this._keepAliveTime, this._keepAliveInterval };

			byte[] inValues = new byte[12];

			for (int index = 0; index < data.Length; index++)
			{
				inValues[index * sizeof(uint) + 3] = (byte)(data[index] >> 24 & 0xff);
				inValues[index * sizeof(uint) + 2] = (byte)(data[index] >> 16 & 0xff);
				inValues[index * sizeof(uint) + 1] = (byte)(data[index] >> 8 & 0xff);
				inValues[index * sizeof(uint) + 0] = (byte)(data[index] >> 0 & 0xff);
			}

			return inValues;
		}

		#endregion
	}
}